#include <tasks_manager/task_manager_node.h>

// 获取当前时间信息
pair<string,string> TaskManagerNode::GetNowTimeInfo(){
    pair<string,string> time_info;
    std::time_t now = std::time(nullptr);
    std::tm* local_time = std::localtime(&now);
    DateFormat datetime(local_time);
    time_info.first = datetime.GetWeekDay();
    time_info.second = datetime.GetHour() + "-" + datetime.GetMinute();
    return time_info;
    // cout << "month: " << datetime.GetMonth().c_str() << ", day: " << datetime.GetDay().c_str() << ", week: " << datetime.GetWeekDay().c_str() << endl;
    // cout << "month: " << datetime.GetMonthInt() << ", day: " << datetime.GetDayInt() << ", week: " << datetime.GetWeekDayInt() << endl;
    // cout << "hour: " << datetime.GetHour().c_str() << ", minute: " << datetime.GetMinute().c_str() << ", second: " << datetime.GetSecond().c_str() << endl;
}

// 定时任务运行检测
void TaskManagerNode::TimerTaskRunning(){
    cout << "[TimerTaskDetection] TimerTaskRunning start..., thread_id=" 
        << this_thread::get_id()
        << endl;
    unordered_map<string, bool> timertask_running_map;
    bool timertask_need_undock_flag = false; //此flag主要用于电量循环判断，需要退桩则执行退桩操作
    while(!ros::isShuttingDown()){
        ros::spinOnce();
        // ros::Duration(0.01).sleep();     //5秒检测一次 此参数需要设置可调
        ros::Duration(5.0).sleep();     //5秒检测一次 此参数需要设置可调

        // 获取当前时间
        pair<string,string> time_info = GetNowTimeInfo();
        int weekday_index = -1;
        for(int i = 0; i < __week_days.size(); ++i){
            if(time_info.first == __week_days[i]){
                weekday_index = i;
            }
        }
        if(weekday_index == -1) continue;
        std::ostringstream oss;
        long timestamp = ros::Time::now().sec;
        oss << std::put_time(localtime(&(timestamp)), "%Y_%m_%d_%H_%M");
        string time_id = oss.str();   //分钟级
        cout << "[TimerTaskDetection] curr_time: " << time_info.first << ", " << time_info.second 
            << ", weekday_index: " << weekday_index 
            << ", time_id: " << time_id
            << endl;

        // 定时任务触发时，如果是充电中且电量<阈值，下发任务到任务清单，实时监听电量，到达阈值后，判断任务清单是否为空，不为空且存在定时任务情况下，执行退桩操作（新增逻辑）
        // 电量判断  
        if(__hardware_state_ptr){
            ros::param::param<int>("/timertask/cancel_charge", __timertask_cancel_charge, 90);     //充电中电量判断
            ros::param::param<int>("/timertask/no_dc_charge", __timertask_no_dc_charge, 20);      //非充电中电量判定  
            bool in_dc_state = int(__hardware_state_ptr->bat_state) == 1;
            int  bat_percentage = int(__hardware_state_ptr->bat_percentage);
            // 充电中且>= 90 退桩
            if(in_dc_state && bat_percentage >= __timertask_cancel_charge){
                if(!__online_tasks_deque.empty() && timertask_need_undock_flag){
                    // 是否存在定时任务
                    bool has_timer_task = false;
                    for(auto& taskgroup_ptr : __online_tasks_deque){
                        if(!taskgroup_ptr->timertask_id.empty()){
                            has_timer_task = true;
                            break;
                        }
                    }
                    if(has_timer_task){
                        auto front_taskgroup = __online_tasks_deque.front();
                        if(front_taskgroup->group_name == "charging"){
                            Status status = CancelTask2NavModule(front_taskgroup->task_list.front());
                            LogPub("INFO", string("检测到定时任务，开始退桩。当前电量 ") + to_string(bat_percentage)
                                    + ", timertask_cancel_charge is " + to_string(__timertask_cancel_charge));
                            // 等待状态反馈
                            if(!status.success){
                                LogPub("ERROR", "[定时任务]Cancel failed! error=" + status.message);
                            }
                            timertask_need_undock_flag = false;     //定时任务下发时，已执行退桩操作，状态置为false
                        }
                    }
                }                
            }
        }      

        
        // 获取当前定时任务信息
        vector<TimerTask> timer_tasks = __task_db_ptr->GetTimerTaskList();
        if(timer_tasks.empty()) continue;
        // 遍历定时任务列表
        for(auto& timer_task : timer_tasks){
            // 检测定时任务数据
            if(!timer_task.enable) continue;    //使能开关检测
            if(__map_name.empty()) continue;
            if(!timer_task.multi_maps_shared && timer_task.map_name != __map_name) continue;    //地图名称检测
            cout << "--> timer_task: " << timer_task.timertask_name 
                << ", start_time: " << timer_task.start_time 
                << ", forced_end_time: " << timer_task.forced_end_time
                << ", enable: " << timer_task.enable
                << ", multi_maps_shared: " << timer_task.multi_maps_shared
                << ", map_name: " << timer_task.map_name
                << ", timetable: ";
                for(auto& item : timer_task.timetable){
                    cout << item;
                }
                cout << endl;
            string start_time = timer_task.start_time;                  //开始时间检测
            if(timer_task.start_time !=  time_info.second) continue;    
            vector<int> timetable = timer_task.timetable;               //周期检测
            if(timetable.size() != __week_days.size()){
                cout << "[TimerTaskDetection] timetable size error." << endl;
                continue;
            }
            if(timetable[weekday_index] != 1) continue;

            string map_id = time_id + "_" + timer_task.timertask_name;     //是否已添加检测
            if(timertask_running_map.find(map_id) != timertask_running_map.end()){
                cout << "[TimerTaskDetection] timertask_running_map find." << endl;
                continue;
            }

            // 检测到新定时任务，插入任务队列
            cout << "[TimerTaskDetection] new timertask_running. push......" << endl;
            // unordered_map<string, TaskGroup> taskgroup_map;     //缓存机制，用于多个同名组合任务，只查询一次
            // string timertask_id = GenerateId();
            // for(auto& task_group : timer_task.taskgroup_list){
            //     if(taskgroup_map.find(task_group.group_name) == taskgroup_map.end()){
            //         // 查表更新组合任务信息
            //         if(!__task_db_ptr->GetTaskGroup(task_group.group_name, task_group)){
            //             LogPub("INFO", string("group_name=" + task_group.group_name + " 查询失败。"));
            //             continue;
            //         }
            //         taskgroup_map[task_group.group_name] = task_group;
            //     }

            //     // 任务队列插入组合任务数据
            //     if(taskgroup_map.count(task_group.group_name) > 0){  
            //         taskgroup_map[task_group.group_name].timertask_name = timer_task.timertask_name;
            //         taskgroup_map[task_group.group_name].timertask_id = timertask_id;
            //         PushTaskGroup(taskgroup_map[task_group.group_name]);
            //     }
            // }

            // 3.2.0版本定时任务内部所有组合任务封装为一个组合任务执行，3.2.1版本再拆开
            timer_task.timertask_id = GenerateId();
            TaskGroup combined_taskgroup;
            combined_taskgroup.group_name = timer_task.timertask_name;
            combined_taskgroup.group_id = GenerateId();
            combined_taskgroup.timertask_name = timer_task.timertask_name;
            combined_taskgroup.timertask_id = timer_task.timertask_id;
            for(auto& task_group : timer_task.taskgroup_list){
                // 查表更新组合任务信息
                if(!__task_db_ptr->GetTaskGroup(task_group.group_name, task_group)){
                    LogPub("INFO", string("group_name=" + task_group.group_name + " 查询失败。"));
                    continue;
                }
                // 追加到队尾
                combined_taskgroup.task_list.insert(combined_taskgroup.task_list.end(),
                    task_group.task_list.begin(), task_group.task_list.end());                   
            }
            timertask_need_undock_flag = true;      //默认定时任务下发时需要退桩操作
            PushTaskGroup(combined_taskgroup);

            // 更新状态
            timertask_running_map[map_id] = true;

            // 电量判断  
            if(__hardware_state_ptr){
                // ros::param::param<int>("/timertask/cancel_charge", __timertask_cancel_charge, 90);     //充电中电量判断
                // ros::param::param<int>("/timertask/no_dc_charge", __timertask_no_dc_charge, 20);      //非充电中电量判定
                bool in_dc_state = int(__hardware_state_ptr->bat_state) == 1;
                int  bat_percentage = int(__hardware_state_ptr->bat_percentage);
                // 充电中且 >= 90可回桩  定时任务触发时，如果是充电中且电量>阈值，直接退桩执行任务
                if(in_dc_state){
                    if(bat_percentage <= __timertask_cancel_charge){
                        LogPub("INFO", string("定时任务 ") + timer_task.timertask_name 
                            + " 下发失败，充电中，当前电量 " + to_string(bat_percentage)
                            + ", timertask_cancel_charge is " + to_string(__timertask_cancel_charge));
                        continue;
                    }
                    else{   //下发取消充电任务
                        if(!__online_tasks_deque.empty()){
                            auto front_taskgroup = __online_tasks_deque.front();
                            if(front_taskgroup->group_name == "charging"){
                                Status status = CancelTask2NavModule(front_taskgroup->task_list.front());
                                LogPub("INFO", string("检测到定时任务，开始退桩。当前电量 ") + to_string(bat_percentage)
                                    + ", timertask_no_dc_charge is " + to_string(__timertask_no_dc_charge));
                                // 等待状态反馈
                                if(!status.success){
                                    LogPub("ERROR", "[定时任务]Cancel failed! error=" + status.message);
                                }
                                timertask_need_undock_flag = false;     //定时任务下发时，已执行退桩操作，状态置为false
                            }
                        }
                        else{
                            LogPub("ERROR", "[定时任务]__online_tasks_deque is empty!");
                            continue;
                        }
                    }

                }
                // 非充电中，>= 20可回桩
                if(!in_dc_state && bat_percentage < __timertask_no_dc_charge){
                    LogPub("INFO", string("定时任务 ") + timer_task.timertask_name 
                        + " 下发失败，非充电中，当前电量 " + to_string(bat_percentage)
                        + ", timertask_no_dc_charge is " + to_string(__timertask_no_dc_charge));
                    continue;                    
                }
            }
        }
    }    
}

